package org.fuckerfucker.urmomboot1.service;

import org.fuckerfucker.urmomboot1.entity.FileMetadata;
import org.fuckerfucker.urmomboot1.repository.FileMetadataRepository;
import org.fuckerfucker.urmomboot1.util.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;


@Service
public class FileUploadService {

    private static final Logger log = LoggerFactory.getLogger(FileUploadService.class);
    private final FileUtils fileUtils;
    private final FileMetadataRepository fileRepo;

    @Value("${file.upload.original-path}")
    private String originalFilePath; // 原始文件存储目录

    @Value("${file.upload.compressed-path}")
    private String compressedFilePath; // 压缩文件存储目录

    @Value("${file.upload.keep-original:false}")
    private boolean keepOriginal; // 是否保留原始文件

    public FileUploadService(FileUtils fileUtils, FileMetadataRepository fileRepo) {
        this.fileUtils = fileUtils;
        this.fileRepo = fileRepo;
    }

    /**
     * 处理文件上传（含去重和压缩）
     */
    public String uploadFile(MultipartFile file) throws Exception {
        // 1. 校验文件
        if (file.isEmpty()) {
            throw new IllegalArgumentException("请选择文件");
        }

        // 2. 计算哈希（核心去重依据）
        String fileHash = fileUtils.calculateFileHash(file);
        log.info("文件哈希计算完成: {}", fileHash);

        // 3. 检查重复
        if (fileRepo.existsByFileHash(fileHash)) {
            FileMetadata existingFile = fileRepo.findByFileHash(fileHash).orElseThrow();
            return "文件已存在！压缩文件路径：" + existingFile.getCompressedFilePath();
        }

        // 4. 准备存储目录
        Path originalDir = Paths.get(originalFilePath.trim());
        Path compressedDir = Paths.get(compressedFilePath.trim());
        try {
            Files.createDirectories(originalDir);
            Files.createDirectories(compressedDir);
            log.info("存储目录准备完成: 原始文件[{}], 压缩文件[{}]", originalDir, compressedDir);
        } catch (IOException e) {
            throw new RuntimeException("无法创建存储目录：" + e.getMessage(), e);
        }

        // 5. 处理原始文件（可选保留）
        String originalFileSavePath = null;
        if (keepOriginal) {
            String extension = getFileExtension(file.getOriginalFilename());
            originalFileSavePath = originalDir.resolve(fileHash + extension).toString();
            Files.write(Paths.get(originalFileSavePath), file.getBytes());
            log.info("原始文件保存: {}", originalFileSavePath);
        }

        // 6. 压缩文件并保存
        String zipFileName = fileHash + ".zip";
        String zipFileSavePath = compressedDir.resolve(zipFileName).toString();
        long compressedSize = fileUtils.compressToZip(
                file.getInputStream(),
                zipFileSavePath,
                file.getOriginalFilename()
        );
        log.info("压缩文件保存: {} (大小: {} bytes)", zipFileSavePath, compressedSize);

        // 7. 保存元数据
        FileMetadata metadata = new FileMetadata();
        metadata.setOriginalFileName(file.getOriginalFilename());
        metadata.setFileHash(fileHash);
        metadata.setOriginalFilePath(originalFileSavePath);
        metadata.setCompressedFilePath(zipFileSavePath);
        metadata.setOriginalFileSize(file.getSize());
        metadata.setCompressedFileSize(compressedSize);
        metadata.setUploadTime(LocalDateTime.now());
        fileRepo.save(metadata);
        log.info("文件元数据已保存: {}", metadata.getId());

        return "上传成功！压缩文件路径：" + zipFileSavePath +
                "（压缩率：" + String.format("%.2f%%", (1 - (double)compressedSize/file.getSize())*100) + "）";
    }


    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String fileName) {
        if (fileName == null || !fileName.contains(".")) {
            return "";
        }
        return fileName.substring(fileName.lastIndexOf("."));
    }
}